package systemInformation;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.snmp4j.PDU;
import org.snmp4j.agent.mo.snmp.DisplayString;
import org.snmp4j.smi.Counter32;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;

import features.SNMPException;
import features.SNMPSession;
import features.SNMPValue;

public class DeviceInfo {
	private final static String DESCRIPTION_OID = 	".1.3.6.1.2.1.25.3.2.1.3";
	
	private final static String STATUS_OID = 		".1.3.6.1.2.1.25.3.2.1.5";
	
	private final static String ERRORS_OID = 		".1.3.6.1.2.1.25.3.2.1.6";
	
	private String description;

	private String status;

	private long errors;

	@SuppressWarnings("unchecked")
	public static DeviceInfo fromPDU(PDU pdu) {
		DeviceInfo info = new DeviceInfo();
		Vector<VariableBinding> variableBindings = pdu.getVariableBindings();
		
		for (VariableBinding variableBinding : variableBindings) {
			if(variableBinding.getOid().compareTo(new OID(DESCRIPTION_OID)) == 0) {
				info.setDescription(((DisplayString) variableBinding.getVariable()).toString());
			} else if(variableBinding.getOid().compareTo(new OID(STATUS_OID)) == 0) {
				info.setStatus(DeviceStatus.fromVariable((Integer32) variableBinding.getVariable()).toString());
			} else if(variableBinding.getOid().compareTo(new OID(ERRORS_OID)) == 0) {
				info.setErrors(((Counter32) variableBinding.getVariable()).getValue());
			}
		}
		
		return info;
	}
	
	public static List<DeviceInfo> fromSession(SNMPSession session) throws SNMPException {
		List<DeviceInfo> devices = new ArrayList<DeviceInfo>();
		List<SNMPValue> lstIndex = session.getColumn(DESCRIPTION_OID);
		List<SNMPValue> lstStatus = session.getColumn(STATUS_OID);
		List<SNMPValue> lstError = session.getColumn(ERRORS_OID);

		for (int i = 0; i < lstIndex.size(); i++) {
			DeviceInfo info = new DeviceInfo();
			
			info.setDescription(lstIndex.get(i).toString());
			info.setStatus(DeviceStatus.fromInt(lstStatus.get(i).toInt()).toString());
			info.setErrors(lstError.get(i).toLong());
			
			devices.add(info);
		}
		
		return devices;
	}
	
	@Override
	public String toString() {
		return "DeviceInfo [" + description + ", " + status + ", " + errors + "]";
	}
	
	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public long getErrors() {
		return this.errors;
	}

	public void setErrors(long errors) {
		this.errors = errors;
	}

	public String getStatus() {
		return this.status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((description == null) ? 0 : description.hashCode());
		result = prime * result + (int) (errors ^ (errors >>> 32));
		result = prime * result + ((status == null) ? 0 : status.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final DeviceInfo other = (DeviceInfo) obj;
		if (description == null) {
			if (other.description != null)
				return false;
		} else if (!description.equals(other.description))
			return false;
		if (errors != other.errors)
			return false;
		if (status == null) {
			if (other.status != null)
				return false;
		} else if (!status.equals(other.status))
			return false;
		return true;
	}

}
